use std::ops::Add;

/// trait孤儿规则
pub fn start() {}

#[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]
struct Int(i32);

impl Add<i32> for Int {
    type Output = i32;

    fn add(self, rhs: i32) -> Self::Output {
        self.0 + rhs
    }
}

/// 为什么孤儿规则没有起作用，
/// 这是因为 Box<T>在 Rust中属于最常用的类型，
/// 从子 crate 为 Box<Int>这种自定义类型扩展trait实现。
/// 标准库 中根本做不到覆盖所有的 crate 中的各种可能性，
/// 所以必须将 Box<T>开放出来，脱离孤儿规则的限制，
/// 否则就会限制子 crate 要实现的一些功能。
/// 那么 ， Box<T>是怎么做到如此特殊的呢?
/// 这其实是因为 Rust 内部使用了一个叫 #[fundamental]的属性标识，
/// 该属性的作用就是告诉编译器， Box<T>享有“特权”， 不必遵循孤儿规则
/// 除了 Box<T>，还有 Fn、 FnMut、 FnOnce、 Sized 等都加
/// 上了#[fundamental]属性，代表 这些 trait也同样不受孤儿规则的限制
/// 如果看到该属性标识，就应该知道它和孤儿规则有关 。
impl Add<i32> for Box<Int> {
    type Output = i32;

    fn add(self, rhs: i32) -> Self::Output {
        self.0 + rhs
    }
}

// trait孤儿规则
// 因为Add和Option都不属于当前的crate
// impl Add<i32> for Option<Int> {
//     type Output = i32;
//
//     fn add(self, rhs: i32) -> Self::Output {
//         self.map_or(0, |v| v.0 + rhs)
//     }
// }
